package org.wzh.three.jvm.gc;

/**
 * 一次对象得到自我拯救
 * @author ewanhiz
 * 结果:
 *      finalize method executed!
 *      Yes, i am still alive
 *      No, i am dead.
 * SAVE_HOOK 对象的 finalize() 方法确实被 GC 收集器触发过,并且在被收集前成功逃脱了.
 */
public class FinalizeEscapeGC {

    public static FinalizeEscapeGC SAVE_HOOK = null;

    public void isAlive() {
        System.out.println("Yes, i am still alive");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize method executed!");
        FinalizeEscapeGC.SAVE_HOOK = this;
    }

    public static void main(String[] args) throws InterruptedException {
        SAVE_HOOK = new FinalizeEscapeGC();

        // 对象第一次成功拯救自己
        SAVE_HOOK = null;
        System.gc();
        // 因为 finalize 方法优先级很低,所以暂停 0.5s 以等待它
        Thread.sleep(500);
        areYouOk(SAVE_HOOK);

        // 下面这段代码与上面的完全相同, 但是这次自救却失败了
        SAVE_HOOK = null;
        System.gc();
        // 因为 finalize 方法优先级很低,所以暂停 0.5s 以等待它
        Thread.sleep(500);
        areYouOk(SAVE_HOOK);

        /**
         * 任何一个对象的 finalize() 方法都只会被系统自动调用一次.
         * 如果对象面临下一次回收,它的 finalize() 方法不会再次执行.
         */

    }

    public static void areYouOk(FinalizeEscapeGC finalizeEscapeGC) {
        if (SAVE_HOOK != null) {
            SAVE_HOOK.isAlive();
        } else {
            System.out.println("No, i am dead.");
        }
    }
}
